<template>
  <div>
    <div v-if="hasToolbar" class="table-toolbar">
      <!--  工具栏插槽   -->
      <div class="table-toolbar-left">
        <slot name="toolbarBtn"></slot>
      </div>
      <div class="table-toolbar-right flex-center">
        <template v-if="multipleSelection.length > 0">
          <el-tooltip effect="dark" content="删除选中" placement="top">
            <el-icon class="columns-setting-icon" @click="delSelection(multipleSelection)">
              <Delete />
            </el-icon>
          </el-tooltip>
          <el-divider direction="vertical" />
        </template>
        <el-tooltip effect="dark" content="刷新" placement="top">
          <el-icon class="columns-setting-icon" @click="refresh">
            <Refresh />
          </el-icon>
        </el-tooltip>
        <el-divider direction="vertical" />
        <el-tooltip effect="dark" content="列设置" placement="top">
          <el-dropdown :hide-on-click="false" size="small" trigger="click">
            <el-icon class="columns-setting-icon">
              <Setting />
            </el-icon>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item v-for="c in columns" :key="c.prop">
                  <el-checkbox v-model="c.visible" :label="c.label" />
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </el-tooltip>
      </div>
    </div>
    <!--数据表-->
    <el-table
      class="mgb20"
      :style="{ width: '100%', minHeight: tableMinHeight }"
      border
      :data="tableData"
      :row-key="rowKey"
      table-layout="auto"
      :tree-props="{ children: 'children' }"
      @selection-change="handleSelectionChange"
    >
      <template v-for="item in columns" :key="item.prop">
        <el-table-column
          v-if="item.visible"
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          :type="item.type"
          :align="item.align || 'center'"
        >
          <template #default="{ row, $index }">
            <span v-if="item.type === 'index'">{{ getIndex($index) }}</span>
            <slot v-else :name="item.prop" :row="row" :index="$index">
              <template v-if="item.prop == 'operator'">
                <el-button
                  type="warning"
                  size="small"
                  :hidden="item.viewHidden"
                  :icon="View"
                  @click="viewFunc(row)"
                >
                  查看
                </el-button>
                <el-button
                  type="primary"
                  size="small"
                  :hidden="item.editHidden"
                  :icon="Edit"
                  @click="editFunc(row)"
                >
                  编辑
                </el-button>
                <el-button
                  type="danger"
                  size="small"
                  :hidden="item.deleteHidden"
                  :icon="Delete"
                  @click="handleDelete(row)"
                >
                  删除
                </el-button>
              </template>
              <span v-else-if="item.formatter">
                {{ item.formatter(row[item.prop]) }}
              </span>
              <span v-else>
                {{ row[item.prop] }}
              </span>
            </slot>
          </template>
        </el-table-column>
      </template>
    </el-table>

    <el-pagination
      v-if="hasPagination"
      :current-page="currentPage"
      :page-size="pageSize"
      :background="true"
      :layout="layout"
      :total="total"
      @current-change="handleCurrentChange"
      @change="handleCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
  import { PropType, ref, toRefs } from 'vue'
  import { Delete, Edit, Refresh, Setting, View } from '@element-plus/icons-vue'
  import { ElMessageBox } from 'element-plus'
  import { TableColumns } from '@/types/form-option.ts'

  const props = defineProps({
    // 表格相关
    tableData: {
      type: Array,
      default: () => [],
    },
    columns: {
      type: Array as PropType<TableColumns[]>,
      default: () => [],
    },
    rowKey: {
      type: String,
      default: 'id',
    },
    hasToolbar: {
      type: Boolean,
      default: true,
    },
    //  分页相关
    hasPagination: {
      type: Boolean,
      default: true,
    },
    total: {
      type: Number,
      default: 0,
    },
    currentPage: {
      type: Number,
      default: 1,
    },
    pageSize: {
      type: Number,
      default: 10,
    },

    layout: {
      type: String,
      default: 'total, prev, pager, next',
    },
    delFunc: {
      type: Function,
      default: () => {},
    },
    viewFunc: {
      type: Function,
      default: () => {},
    },
    editFunc: {
      type: Function,
      default: () => {},
    },
    delSelection: {
      type: Function,
      default: () => {},
    },
    refresh: {
      type: Function,
      default: () => {},
    },
    changePage: {
      type: Function,
      default: () => {},
    },
    tableMinHeight: {
      type: String,
      default: '450px',
    },
  })

  let {
    tableData,
    columns,
    rowKey,
    hasToolbar,
    hasPagination,
    total,
    currentPage,
    pageSize,
    layout,
    tableMinHeight,
  } = toRefs(props)

  columns.value.forEach(item => {
    if (item.visible === undefined) {
      item.visible = true
    }
  })

  // 当选择项发生变化时会触发该事件
  const multipleSelection = ref<unknown[]>([])
  const handleSelectionChange = (selection: unknown[]) => {
    multipleSelection.value = selection
  }

  // 当前页码变化的事件
  const handleCurrentChange = (val: number) => {
    props.changePage(val)
  }

  const handleDelete = (row: unknown) => {
    ElMessageBox.confirm('确定要删除吗？', '提示', {
      type: 'warning',
    })
      .then(async () => {
        props.delFunc(row)
      })
      .catch(() => {})
  }

  const getIndex = (index: number) => {
    return index + 1 + (currentPage.value - 1) * pageSize.value
  }
</script>

<style scoped>
  .table-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    margin-bottom: 10px;
  }

  .columns-setting-icon {
    display: block;
    font-size: 18px;
    cursor: pointer;
    color: #676767;
  }
</style>
<style></style>
